package net.sf.rose.web.util;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.business.bean.system.FileBean;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import net.sf.rose.boot.BootStart;
import net.sf.rose.boot.BootStrap;
import net.sf.rose.boot.bean.StaticLocationBean;
import net.sf.rose.file.util.FileUtils;
import net.sf.rose.jdbc.KeyGenerator;
import net.sf.rose.jdbc.PageBean;
import net.sf.rose.util.BeanWrapper;
import net.sf.rose.util.RoseRuntimeException;
import net.sf.rose.util.StringUtil;

/** 
 * @author fengjian E-mail: 9110530@qq.com 
 * @version 创建时间：2016年10月2日
 * 类说明：Web服务通用工具类
 */
@Root
public class WebUtils implements BootStart {

	private static final String ENCODING_DEFAULT = "UTF-8";
	private static final String TEXT_TYPE = "text/plain";
	private static final String JSON_TYPE = "application/json";
	private static final String XML_TYPE = "text/xml";
	private static final String HTML_TYPE = "text/html";

	/** 服务器Http URL访问路径 */
	public static String SERVER_URL = null;

	/** 前端网页的存放路径 */
	public static File WEB_APP_PATH = null;

	/**
	 * 从Http请求中获取所有的请求参数，转化为Map类型
	 * @param request - Http请求
	 * @return 转化后的键值对
	 */
	public static Map<String, Object> getRequestData(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		Object val = null;
		String[] arr = null;
		Map<?, ?> m = request.getParameterMap();
		for (Object o : m.keySet()) {
			arr = (String[]) m.get(o);
			String key = o.toString();
			if (key.indexOf("[]") != -1) {
				key = key.substring(0, key.indexOf("[]"));
			}
			// 如果是数组
			if (arr.length > 1) {
				map.put(key, arr);
			} else {
				val = arr[0];
				// 如果不是空值
				if (!val.toString().equals("")) {
					map.put(key, val);
				}
			}
		}
		if (map.get("sortField") != null) {
			map.put("orderBy", map.get("sortField").toString() + ',' + map.get("sortOrder"));
		}
		return map;
	}

	/**
	 * 从Http请求中获取所有的请求参数，转化为Map类型
	 * @param request - Http请求
	 * @return 转化后的键值对
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getRequestBean(HttpServletRequest request, Class<?> clazz) {
		T object = null;
		try {
			object = (T) clazz.newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
		BeanWrapper bw = new BeanWrapper(object);
		for (String name : bw.getAllFieldNames()) {
			String val = request.getParameter(name);
			if (val != null && !val.trim().equals("")) {
				bw.set(name, val);
			}
		}
		return object;
	}

	/**
	 * 获取分页对象
	 * @param request - Http请求
	 * @return 分页对象
	 */
	public static PageBean getPageBean(HttpServletRequest request) {
		PageBean page = new PageBean();
		String pageIndex = request.getParameter("pageIndex");
		String pageSize = request.getParameter("pageSize");
		page.setPageIndex(pageIndex == null ? 0 : Integer.parseInt(pageIndex));
		page.setpageSize(pageSize == null ? 0 : Integer.parseInt(pageSize));
		return page;
	}

	/**
	 * 设置用户对象缓存
	 * @param request - Http请求
	 * @param user    - 用户对象实例
	 */
	public static String setUserBeanCache(HttpServletRequest request, Object user) {
		String token = request.getParameter("_token");
		// 如果没有token就生成一个
		if (token == null) {
			return SessionUtils.addUserBeanCache(user);
		} else {
			Object obj = SessionUtils.getUserBeanCache(token);
			// 如果根据token在缓存中没有找到
			if (obj == null) {
				return SessionUtils.addUserBeanCache(user);
			}
			// 如果找到了对象与缓存中的对象不是同一个对象，则删除缓存中的对象并重新添加
			else if (!obj.toString().equals(user.toString())) {
				SessionUtils.removeUserBeanCache(token);
				return SessionUtils.addUserBeanCache(user);
			}
			return token;
		}
	}

	/**
	 * 获取用户对象缓存
	 * @param request - Http请求
	 * @return 用户对象实例
	 */
	public static Object getUserBeanCache(HttpServletRequest request) {
		String token = request.getParameter("_token");
		if (token == null) {
			return null;
		}
		return SessionUtils.getUserBeanCache(token);
	}

	/**
	 * 保存图片文件
	 * @param request - Http请求
	 * @return 所有的图片文件列表数据，每一项数组包含源文件名和访问路径
	 */
	public static List<FileBean> saveImage(HttpServletRequest request) {
		List<FileBean> list = new ArrayList<>();
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
		// 有图片则上传图片
		if (fileMap != null) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
			String ymd = sdf.format(new Date());
			File path = new File(FileUtils.IMAGE_PATH, ymd);
			// 创建文件夹
			if (!path.exists()) {
				path.mkdirs();
			}
			try {
				for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
					// 上传文件
					FileBean fb = new FileBean();
					MultipartFile mf = entity.getValue();
					byte[] data = mf.getBytes();
					String origName = mf.getOriginalFilename();// 获取原文件名
					String subfix = origName.substring(origName.lastIndexOf("."));
					fb.setOriginalName(origName);
					fb.setType(subfix);
					fb.setSize(data.length);
					subfix = KeyGenerator.getSystemUUID() + subfix;
					File uploadFile = new File(path, subfix);
					FileCopyUtils.copy(mf.getBytes(), uploadFile);
					System.out.println(uploadFile);
					fb.setFileName(subfix);
					fb.setUrl("/images/" + ymd + '/' + subfix);
					list.add(fb);
				}
			} catch (IOException e) {
				throw new RoseRuntimeException(e.getMessage());
			}
		}
		return list;
	}

	/**
	 * 返回字符串给Http响应
	 * @param response - Http响应
	 * @param contentType - 头文件类型
	 * @param content - 文本内容
	 * @throws IOException - 异常
	 */
	public static void render(HttpServletResponse response, String contentType, final String content) throws IOException {
		// 设置headers参数
		String fullContentType = contentType + ";charset=" + ENCODING_DEFAULT;
		response.setContentType(fullContentType);

		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);

		response.getWriter().write(content);
		response.getWriter().flush();
	}

	/**
	 * 直接输出文本.
	 * @param response - Http响应
	 * @param text - 文本内容
	 * @throws IOException - 异常
	 */
	public static void renderText(HttpServletResponse response, String text) throws IOException {
		render(response, TEXT_TYPE, text);
	}

	/**
	 * 直接输出HTML.
	 * @param response - Http响应
	 * @param html - html文件正文
	 * @throws IOException - 异常
	 */
	public static void renderHtml(HttpServletResponse response, String html) throws IOException {
		render(response, HTML_TYPE, html);
	}

	/**
	 * 直接输出XML.
	 * @param response - Http响应
	 * @param xml - xml文件正文
	 * @throws IOException - 异常
	 */
	public static void renderXml(HttpServletResponse response, String xml) throws IOException {
		render(response, XML_TYPE, xml);
	}

	/**
	 * 直接输出JSON.
	 * @param response - Http响应
	 * @param json - Json格式正文
	 * @throws IOException - 异常 
	 */
	public static void renderJson(HttpServletResponse response, String json) throws IOException {
		render(response, JSON_TYPE, json);
	}

	/**
	 * 直接输出JSON. 
	 * @param response - Http响应
	 * @param object - Java对象,将被转化为json字符串.
	 * @throws IOException - 异常
	 */
	public static void renderJson(HttpServletResponse response, Object object) throws IOException {
		String jsonString = StringUtil.render(object);
		render(response, JSON_TYPE, jsonString);
	}

	/**
	 * 输出图片等二进制格式
	 * @param response - Http响应
	 * @param data - 字节流
	 * @param type - 类型
	 * @throws IOException - 异常
	 */
	public static void renderImage(HttpServletResponse response, byte[] data, String type) throws IOException {
		response.setContentType(type);
		OutputStream out = response.getOutputStream();
		out.write(data, 0, data.length);
		out.flush();
		out.close();
	}

	/** 是否需要启动 */
	@Attribute
	private boolean needStart = false;

	/** Http服务器访问URL地址 */
	@Element
	private String http = "http://localhost";

	/** Http服务器访问端口 */
	@Element(required = false)
	private int port = 80;

	/** Http服务器访问项目空间 */
	@Element(required = false)
	private String contextPath = "";

	/**
	 * 需要启动
	 */
	@Override
	public boolean needStart() {
		return needStart;
	}

	/**
	 * 启动执行的方法
	 */
	@Override
	public void start() {
		// 服务器Http URL访问路径
		String url = http;
		if (port != 80) {
			url = url + ':' + port;
		}
		if (!contextPath.equals("")) {
			url = url + contextPath;
		}
		url = url + '/';
		SERVER_URL = url;
		// 从Web项目路径中获取前端html页面存储路径
		List<StaticLocationBean> list = BootStrap.getBootBean().getLocationList();
		for (StaticLocationBean bean : list) {
			if (bean.getKey().equals("webapp")) {
				WEB_APP_PATH = bean.getFile();
				break;
			}
		}
		// 如果没有就在根目录下找前端html文件
		if (WEB_APP_PATH == null) {
			File file = BootStrap.getResourceFile("webapp");
			if (file.exists()) {
				WEB_APP_PATH = file;
			}
		}
	}

	public boolean isNeedStart() {
		return needStart;
	}

	public void setNeedStart(boolean needStart) {
		this.needStart = needStart;
	}

	public String getHttp() {
		return http;
	}

	public void setHttp(String http) {
		this.http = http;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public String getContextPath() {
		return contextPath;
	}

	public void setContextPath(String contextPath) {
		this.contextPath = contextPath;
	}

}
